home *** CD-ROM | disk | FTP | other *** search
- #define LIBQTOOLS_CORE
- #include "../include/libqtools.h"
- #include "../include/libqbuild.h"
- #include "TDDD.h"
-
- #define CLUSTER_POINTS (CLUSTER_FACES / 3)
- #define CLUSTER_GROUPS 16
- #define CLUSTER_SUBGROUP (CLUSTER_FACES / 3)
-
- int TDDDmax_pcount = 0;
- int TDDDmax_ecount = 0;
- int TDDDmax_tcount = 0;
- int TDDDmax_gcount = 0;
- struct points *TDDDpoints = 0;
- struct edges *TDDDedges = 0;
- struct faces *TDDDfaces = 0;
- int TDDDgroups = 0;
- int *TDDDgroupsizes = 0;
- struct facesubgroup **TDDDgroup = 0;
- struct brush5 *TDDDbrushes = 0;
-
- int TDDDnumpoints = 0;
- int TDDDnumedges = 0;
- int TDDDnumfaces = 0;
- int TDDDnumgroups = 0;
- int TDDDnumobjects = 0;
-
- int nummapbrushes; /* 4 */
-
- void AllocTDDDSubGroup(register unsigned short int faceNum, register char *texname)
- {
- unsigned short int i, j;
-
- #if (WORDS_BIGENDIAN == 0)
- faceNum = BigShort(faceNum);
- #endif
-
- if (!TDDDgroup) {
- if (!(TDDDgroup = (struct facesubgroup **)tmalloc(CLUSTER_GROUPS * sizeof(struct facesubgroup *))))
- Error(failed_memoryunsize, "group");
- if (!(TDDDgroupsizes = (int *)tmalloc(CLUSTER_GROUPS * sizeof(int))))
- Error(failed_memoryunsize, "group");
- if (!(TDDDbrushes = (struct brush5 *)tmalloc(CLUSTER_GROUPS * sizeof(struct brush5))))
- Error(failed_memoryunsize, "brush");
- }
-
- if (TDDDgroups >= TDDDmax_gcount) {
- if (!(TDDDgroup = (struct facesubgroup **)trealloc(TDDDgroup, ((TDDDmax_gcount += CLUSTER_GROUPS) * sizeof(struct facesubgroup *)))))
- Error(failed_memoryunsize, "group");
- if (!(TDDDgroupsizes = (int *)trealloc(TDDDgroupsizes, (TDDDmax_gcount * sizeof(int)))))
- Error(failed_memoryunsize, "group");
- if (!(TDDDbrushes = (struct brush5 *)trealloc(TDDDbrushes, (TDDDmax_gcount * sizeof(struct brush5)))))
- Error(failed_memoryunsize, "brush");
- }
-
- for (i = 0; i < TDDDgroups; i++)
- if (!__strncmp(TDDDgroup[i]->name, texname, 18))
- break;
-
- if (!TDDDgroup[i])
- if (!(TDDDgroup[i] = (struct facesubgroup *)tmalloc((CLUSTER_SUBGROUP * sizeof(unsigned short int)) + sizeof(struct facesubgroup))))
- Error(failed_memoryunsize, "subgroup");
-
- if (TDDDgroup[i]->count >= TDDDgroupsizes[i])
- if (!(TDDDgroup[i] = (struct facesubgroup *)trealloc(TDDDgroup[i], ((TDDDgroupsizes[i] += CLUSTER_SUBGROUP) * sizeof(unsigned short int)) + sizeof(struct facesubgroup))))
- Error(failed_memoryunsize, "subgroup");
-
- if (i == TDDDgroups) {
- __strncpy(TDDDgroup[i]->name, texname, 18);
- TDDDbrushes[i].fullscale = BigShort(1);
- TDDDbrushes[i].flags = BigShort(BRS_COLOR);
- TDDDbrushes[i].wflags = BigShort(BRW_REPEA);
- TDDDgroups++;
- TDDDnumgroups++;
- }
-
- for (j = 0; j < TDDDgroup[i]->count; j++)
- if (faceNum == TDDDgroup[i]->facelist[j])
- return;
-
- TDDDgroup[i]->facelist[j] = faceNum;
- TDDDgroup[i]->count++;
- }
-
- unsigned short int AllocTDDDPoint(register vector * point)
- {
- unsigned short int i;
-
- #if (WORDS_BIGENDIAN == 0)
- point->x = BigLong(point->x);
- point->y = BigLong(point->y);
- point->z = BigLong(point->z);
- #endif
-
- if (!TDDDpoints)
- if (!(TDDDpoints = (struct points *)tmalloc((CLUSTER_POINTS * sizeof(vector)) + sizeof(struct points))))
- Error(failed_memoryunsize, "point");
-
- if (TDDDpoints->pcount >= TDDDmax_pcount)
- if (!(TDDDpoints = (struct points *)trealloc(TDDDpoints, ((TDDDmax_pcount += CLUSTER_POINTS) * sizeof(vector)) + sizeof(struct points))))
- Error(failed_memoryunsize, "point");
-
- for (i = 0; i < TDDDpoints->pcount; i++) {
- if (point->x == TDDDpoints->points[i].x)
- if (point->y == TDDDpoints->points[i].y)
- if (point->z == TDDDpoints->points[i].z)
- return i;
- }
- TDDDpoints->points[i].x = point->x;
- TDDDpoints->points[i].y = point->y;
- TDDDpoints->points[i].z = point->z;
- TDDDpoints->pcount++;
- TDDDnumpoints++;
-
- return i;
- }
-
- unsigned short int AllocTDDDEdge(register unsigned short int point0, register unsigned short int point1)
- {
- unsigned short int i;
-
- #if (WORDS_BIGENDIAN == 0)
- point0 = BigShort(point0);
- point1 = BigShort(point1);
- #endif
-
- if (!TDDDedges)
- if (!(TDDDedges = (struct edges *)tmalloc((CLUSTER_EDGES * sizeof(unsigned short int) * 2) + sizeof(struct edges))))
- Error(failed_memoryunsize, "edge");
-
- if (TDDDedges->ecount >= TDDDmax_ecount)
- if (!(TDDDedges = (struct edges *)trealloc(TDDDedges, ((TDDDmax_ecount += CLUSTER_EDGES) * sizeof(unsigned short int) * 2) + sizeof(struct edges))))
- Error(failed_memoryunsize, "edge");
-
- for (i = 0; i < TDDDedges->ecount; i++) {
- if (point0 == TDDDedges->edges[i][0])
- if (point1 == TDDDedges->edges[i][1])
- return i;
- }
- TDDDedges->edges[i][0] = point0;
- TDDDedges->edges[i][1] = point1;
- TDDDedges->ecount++;
- TDDDnumedges++;
- return i;
- }
-
- unsigned short int AllocTDDDFace(register unsigned short int connect0, register unsigned short int connect1, register unsigned short int connect2)
- {
- unsigned short int i;
-
- #if (WORDS_BIGENDIAN == 0)
- connect0 = BigShort(connect0);
- connect1 = BigShort(connect1);
- connect2 = BigShort(connect2);
- #endif
-
- if (!TDDDfaces)
- if (!(TDDDfaces = (struct faces *)tmalloc((CLUSTER_FACES * sizeof(unsigned short int) * 3) + sizeof(struct faces))))
- Error(failed_memoryunsize, "face");
-
- if (TDDDfaces->tcount >= TDDDmax_tcount)
- if (!(TDDDfaces = (struct faces *)trealloc(TDDDfaces, ((TDDDmax_tcount += CLUSTER_FACES) * sizeof(unsigned short int) * 3) + sizeof(struct faces))))
- Error(failed_memoryunsize, "face");
-
- for (i = 0; i < TDDDfaces->tcount; i++) {
- if (connect0 == TDDDfaces->connects[i][0])
- if (connect1 == TDDDfaces->connects[i][1])
- if (connect2 == TDDDfaces->connects[i][2])
- return i;
- }
- TDDDfaces->connects[i][0] = connect0;
- TDDDfaces->connects[i][1] = connect1;
- TDDDfaces->connects[i][2] = connect2;
- TDDDfaces->tcount++;
- TDDDnumfaces++;
- return i;
- }
-
- bool SaveFace(vec3_t point0, vec3_t point1, vec3_t point2, register char *texname)
- {
- unsigned short int face, p0, p1, p2;
- vector p;
-
- p.x = float2fract(point0[0]);
- p.y = float2fract(point0[1]);
- p.z = float2fract(point0[2]);
- p0 = AllocTDDDPoint(&p);
- p.x = float2fract(point1[0]);
- p.y = float2fract(point1[1]);
- p.z = float2fract(point1[2]);
- p1 = AllocTDDDPoint(&p);
- p.x = float2fract(point2[0]);
- p.y = float2fract(point2[1]);
- p.z = float2fract(point2[2]);
- p2 = AllocTDDDPoint(&p);
-
- face = AllocTDDDFace(AllocTDDDEdge(p0, p1),
- AllocTDDDEdge(p1, p2),
- AllocTDDDEdge(p2, p0));
- AllocTDDDSubGroup(face, texname);
- return TRUE;
- }
-
- bool SetForm(register HANDLE outFile, register int *last, register int ID)
- {
- int Form[3];
-
- Form[0] = BigLong(ID_FORM);
- Form[1] = BigLong(*last);
- Form[2] = BigLong(ID);
-
- *last = __ltell(outFile) + 8;
- __write(outFile, Form, 12);
-
- return TRUE;
- }
-
- bool SetRoot(register HANDLE outFile, register int *last, register int ID)
- {
- int Root[2];
-
- Root[0] = BigLong(ID);
- Root[1] = BigLong(*last);
-
- *last = __ltell(outFile) + 8;
- __write(outFile, Root, 8);
-
- return TRUE;
- }
-
- bool SetEndM(register HANDLE outFile, register int ID)
- {
- int EndM[2];
-
- EndM[0] = BigLong(ID);
- EndM[1] = BigLong(0);
-
- __write(outFile, EndM, 8);
- TDDDnumobjects++;
-
- return TRUE;
- }
-
- bool VerRoot(register HANDLE outFile, register int *last, register int ID)
- {
- int this = __ltell(outFile);
- int Root[2];
-
- __lseek(outFile, *last - 8, SEEK_SET);
- *last = this - *last;
-
- Root[0] = BigLong(ID);
- Root[1] = BigLong(*last);
-
- __write(outFile, Root, 8);
- __lseek(outFile, this, SEEK_SET);
-
- return TRUE;
- }
-
- bool SetClassName(register HANDLE outFile, register char *className)
- {
- int Class[2];
-
- Class[0] = BigLong(ID_NAME);
- Class[1] = BigLong(18);
-
- __write(outFile, Class, 8);
- __write(outFile, className, __strlen(className));
-
- return TRUE;
- }
-
- bool SetEntity(register HANDLE outFile, register char *variable, register char *content)
- {
- int nameLen = __strlen(content);
- struct {
- int Entity[2];
- struct texture4 brushTex;
- } ent;
-
- nameLen = ((nameLen + 1) & ~1);
- nameLen++;
- nameLen = ((nameLen + 1) & ~1);
- __bzero(&ent.brushTex, sizeof(struct texture4));
- __strncpy(ent.brushTex.label, variable, 18 + 1);
-
- ent.Entity[0] = BigLong(ID_TXT4);
- ent.Entity[1] = BigLong(sizeof(struct texture4) + nameLen);
- ent.brushTex.flags = BigShort(TXT_DISAB);
- ent.brushTex.length = (char)nameLen;
-
- __write(outFile, &ent, 8 + sizeof(struct texture4));
- __write(outFile, content, nameLen - 1);
- __write(outFile, "\0", 1);
-
- return TRUE;
- }
-
- bool SetBrushes(register HANDLE outFile)
- {
- int lastBrush, i;
-
- for (i = 0; i < TDDDgroups; i++) {
- /*
- * write only a subgroup if there are more than one
- * and if the subgroup contains members
- */
- if ((TDDDgroups > 1) && (TDDDgroup[i]->count > 0)) {
- SetRoot(outFile, &lastBrush, ID_FGRP);
- __write(outFile, TDDDgroup[i], 20 + (sizeof(unsigned short int) * TDDDgroup[i]->count));
-
- VerRoot(outFile, &lastBrush, ID_FGRP);
- __strncpy(TDDDbrushes[i].subgrp, TDDDgroup[i]->name, 18);
- }
- SetRoot(outFile, &lastBrush, ID_BRS5);
- TDDDbrushes[i].length = ((__strlen(TDDDgroup[i]->name + 1) + 1) & ~1);
- __write(outFile, &TDDDbrushes[i], sizeof(struct brush5));
-
- __write(outFile, TDDDgroup[i]->name, TDDDbrushes[i].length);
- VerRoot(outFile, &lastBrush, ID_BRS5);
- TDDDgroup[i]->count = 0;
- }
- TDDDgroups = 0;
-
- return TRUE;
- }
-
- bool SetPoints(register HANDLE outFile)
- {
- if (TDDDpoints) {
- if (TDDDpoints->pcount) {
- int len = (sizeof(vector) * TDDDpoints->pcount) + sizeof(unsigned short int);
- int Points[2];
-
- Points[0] = BigLong(ID_PNTS);
- Points[1] = BigLong(len);
-
- __write(outFile, Points, 8);
- __write(outFile, TDDDpoints, len);
-
- TDDDpoints->pcount = 0;
- }
- }
- return TRUE;
- }
-
- bool SetEdges(register HANDLE outFile)
- {
- if (TDDDedges) {
- if (TDDDedges->ecount) {
- int len = sizeof(unsigned short int) * ((TDDDedges->ecount * 2) + 1);
- int Edges[2];
-
- Edges[0] = BigLong(ID_EDGE);
- Edges[1] = BigLong(len);
-
- __write(outFile, Edges, 8);
- __write(outFile, TDDDedges, len);
-
- TDDDedges->ecount = 0;
- }
- }
- return TRUE;
- }
-
- bool SetFaces(register HANDLE outFile)
- {
- if (TDDDfaces) {
- if (TDDDfaces->tcount) {
- int len = sizeof(unsigned short int) * ((TDDDfaces->tcount * 3) + 1);
- int Faces[2];
-
- Faces[0] = BigLong(ID_FACE);
- Faces[1] = BigLong(len);
-
- __write(outFile, Faces, 8);
- __write(outFile, TDDDfaces, len);
-
- TDDDfaces->tcount = 0;
- }
- }
- return TRUE;
- }
-
- bool SetOtherDefaults(register HANDLE outFile, register struct entity * ent)
- {
- double posx = 0;
- double posy = 0;
- double posz = 0;
- int points, len, i;
- struct axis axis =
- {
- {0x00010000, 0x00000000, 0x00000000},
- {0x00000000, 0x00010000, 0x00000000},
- {0x00000000, 0x00000000, 0x00010000}};
- struct posi position =
- {
- {0, 0, 0}};
- struct shap shape;
- struct colr colour;
- int Defs[2];
-
- axis.xaxis.x = axis.yaxis.y = axis.zaxis.z = BigLong(0x00010000);
- shape.shape = BigShort(SH_AXIS);
- shape.lamp = BigShort(LP2_NOLAM);
-
- if (ent) {
- position.position.x = float2fract(ent->origin[0]);
- position.position.y = float2fract(ent->origin[1]);
- position.position.z = float2fract(ent->origin[2]);
- if (ent->style) {
- struct {
- int Light[2];
- struct int1 light;
- } lit;
-
- shape.lamp = BigShort(LP2_POINT);
-
- lit.Light[0] = BigLong(ID_INT1);
- lit.Light[1] = BigLong(sizeof(struct int1));
- lit.light.intensity.x = lit.light.intensity.y = lit.light.intensity.z = BigFloat(((unsigned int)ent->light << 22) / 75);
-
- __write(outFile, &lit, 8 + sizeof(struct int1));
- }
- }
-
- if (TDDDpoints)
- if (TDDDpoints->pcount) {
- struct {
- int Attr[2];
- struct bbox bound;
- } att;
- struct faceattr *attr = (struct faceattr *)tmalloc((TDDDfaces->tcount * sizeof(rgb)) + sizeof(struct faceattr));
-
- att.bound.maxs.x = att.bound.maxs.y = att.bound.maxs.z = 0x80000000;
- att.bound.mins.x = att.bound.mins.y = att.bound.mins.z = 0x7FFFFFFF;
-
- for (points = 0; points < TDDDpoints->pcount; points++) {
- if (TDDDpoints->points[points].x > att.bound.maxs.x)
- att.bound.maxs.x = TDDDpoints->points[points].x;
- else if (TDDDpoints->points[points].x < att.bound.mins.x)
- att.bound.mins.x = TDDDpoints->points[points].x;
- if (TDDDpoints->points[points].y > att.bound.maxs.y)
- att.bound.maxs.y = TDDDpoints->points[points].y;
- else if (TDDDpoints->points[points].y < att.bound.mins.y)
- att.bound.mins.y = TDDDpoints->points[points].y;
- if (TDDDpoints->points[points].z > att.bound.maxs.z)
- att.bound.maxs.z = TDDDpoints->points[points].z;
- else if (TDDDpoints->points[points].z < att.bound.mins.z)
- att.bound.mins.z = TDDDpoints->points[points].z;
- posx += fract2float(TDDDpoints->points[points].x);
- posy += fract2float(TDDDpoints->points[points].y);
- posz += fract2float(TDDDpoints->points[points].z);
- }
- position.position.x = BigLong(float2fract(posx / TDDDpoints->pcount));
- position.position.y = BigLong(float2fract(posy / TDDDpoints->pcount));
- position.position.z = BigLong(float2fract(posz / TDDDpoints->pcount));
-
- att.Attr[0] = BigLong(ID_BBOX);
- att.Attr[1] = BigLong(sizeof(struct bbox));
- att.bound.maxs.x = BigLong(att.bound.maxs.x - BigLong(position.position.x));
- att.bound.maxs.y = BigLong(att.bound.maxs.y - BigLong(position.position.y));
- att.bound.maxs.z = BigLong(att.bound.maxs.z - BigLong(position.position.z));
- att.bound.mins.x = BigLong(att.bound.mins.x - BigLong(position.position.x));
- att.bound.mins.y = BigLong(att.bound.mins.y - BigLong(position.position.y));
- att.bound.mins.z = BigLong(att.bound.mins.z - BigLong(position.position.z));
-
- __write(outFile, &att, 8 + sizeof(struct bbox));
-
- attr->count = BigShort(TDDDfaces->tcount);
- for (i = 0; i < TDDDfaces->tcount; i++) {
- attr->attr[i].r = 0xFF;
- attr->attr[i].g = 0xFF;
- attr->attr[i].b = 0xFF;
- }
- len = (TDDDfaces->tcount * sizeof(rgb)) + sizeof(unsigned short int);
- len = ((len + 1) & ~1);
- att.Attr[1] = BigLong(len);
-
- att.Attr[0] = BigLong(ID_CLST);
- __write(outFile, att.Attr, 8);
- __write(outFile, &attr, len);
- att.Attr[0] = BigLong(ID_RLST);
- __write(outFile, att.Attr, 8);
- __write(outFile, &attr, len);
- att.Attr[0] = BigLong(ID_TLST);
- __write(outFile, att.Attr, 8);
- __write(outFile, &attr, len);
-
- tfree(attr);
- }
-
- Defs[0] = BigLong(ID_AXIS);
- Defs[1] = BigLong(sizeof(struct axis));
- __write(outFile, Defs, 8);
- __write(outFile, &axis, sizeof(struct axis));
-
- Defs[0] = BigLong(ID_POSI);
- Defs[1] = BigLong(sizeof(struct posi));
- __write(outFile, Defs, 8);
- __write(outFile, &position, sizeof(struct posi));
-
- Defs[0] = BigLong(ID_SHP2);
- Defs[1] = BigLong(sizeof(struct shap));
- __write(outFile, Defs, 8);
- __write(outFile, &shape, sizeof(struct shap));
-
- colour.color = 0x00FFFFFF;
- Defs[1] = BigLong(sizeof(struct colr));
-
- Defs[0] = BigLong(ID_COLR);
- __write(outFile, Defs, 8);
- __write(outFile, &colour, sizeof(struct colr));
- Defs[0] = BigLong(ID_REFL);
- __write(outFile, Defs, 8);
- __write(outFile, &colour, sizeof(struct colr));
- Defs[0] = BigLong(ID_TRAN);
- __write(outFile, Defs, 8);
- __write(outFile, &colour, sizeof(struct colr));
- Defs[0] = BigLong(ID_SPC1);
- __write(outFile, Defs, 8);
- __write(outFile, &colour, sizeof(struct colr));
-
- return TRUE;
- }
-
- /*
- * convert a Imagine-TDDD to a Quake-Map
- */
-
- /* IFF to pseudo IFF */
- int fileIFFtopIFF(HANDLE iobFile, struct IFFchunk *IFFroot);
- int memIFFtopIFF(unsigned char *iobMem, struct IFFchunk *IFFroot);
-
- /* pseudo IFF to pseudo Brushes */
- void pIFFtopBrushes(__memBase, struct IFFchunk *IFFroot, int iterVal, struct entity *fillEntity);
-
- /* pseudo IFF to pseudo Map */
- void pIFFtopMap(__memBase, struct IFFchunk *IFFroot, int iterVal);
-
- void strlwrcpy(register char *dst, register char *src)
- {
- int i, len = __strlen(src);
-
- for (i = 0; i < len; i++)
- dst[i] = (char)tolower((int)src[i]);
- dst[i] = 0;
- }
-
- int fileIFFtopIFF(register HANDLE iobFile, register struct IFFchunk *IFFroot)
- {
- int processed = 0;
-
- /*
- * small hack -> IFFroot->iter is IFFpart->next
- */
- struct IFFchunk *IFFpart = (struct IFFchunk *)&IFFroot->size;
-
- while (IFFpart->type != BigLong(ID_TOBJ)) {
- int oldOffs;
-
- /*
- * allocate IFFchunk
- */
- IFFpart->next = (struct IFFchunk *)tmalloc(sizeof(struct IFFchunk));
-
- IFFpart = IFFpart->next;
- IFFpart->next = 0;
- IFFpart->iter = 0;
- IFFpart->data = 0;
-
- /*
- * read and parse IFFchunk
- */
- __read(iobFile, IFFpart, 8);
- IFFpart->size = ((BigLong(IFFpart->size) + 1) & ~1);
- processed += 8;
- oldOffs = __ltell(iobFile);
-
- if (IFFpart->type == BigLong(ID_OBJ)) {
- processed += fileIFFtopIFF(iobFile, IFFpart);
- if ((IFFroot->type == BigLong(ID_TDDD)) && (IFFroot->size == processed))
- break;
- }
- else if (IFFpart->type == BigLong(ID_DESC)) {
- processed += fileIFFtopIFF(iobFile, IFFpart);
- if ((IFFroot->type == BigLong(ID_OBJ)) && (IFFroot->size == processed))
- break;
- }
- else if (IFFpart->type != BigLong(ID_TOBJ)) {
- processed += IFFpart->size;
- IFFpart->data = (void *)tmalloc(IFFpart->size + 1);
- __read(iobFile, IFFpart->data, IFFpart->size);
- }
- }
-
- return processed;
- }
-
- int memIFFtopIFF(register unsigned char *iobMem, register struct IFFchunk *IFFroot)
- {
- int processed = 0;
-
- /*
- * small hack -> IFFroot->iter is IFFpart->next
- */
- struct IFFchunk *IFFpart = (struct IFFchunk *)&IFFroot->size;
-
- while (IFFpart->type != BigLong(ID_TOBJ)) {
- /*
- * allocate IFFchunk
- */
- IFFpart->next = (struct IFFchunk *)tmalloc(sizeof(struct IFFchunk));
-
- IFFpart = IFFpart->next;
- IFFpart->next = 0;
- IFFpart->iter = 0;
- IFFpart->data = 0;
-
- /*
- * read and parse IFFchunk
- */
- __memcpy(IFFpart, iobMem, 8);
- iobMem += 8;
- IFFpart->size = ((BigLong(IFFpart->size) + 1) & ~1);
- processed += 8;
-
- if (IFFpart->type == BigLong(ID_OBJ)) {
- processed += memIFFtopIFF(iobMem, IFFpart);
- if ((IFFroot->type == BigLong(ID_TDDD)) && (IFFroot->size == processed))
- break;
- }
- else if (IFFpart->type == BigLong(ID_DESC)) {
- processed += memIFFtopIFF(iobMem, IFFpart);
- if ((IFFroot->type == BigLong(ID_OBJ)) && (IFFroot->size == processed))
- break;
- }
- else if (IFFpart->type != BigLong(ID_TOBJ)) {
- processed += IFFpart->size;
- IFFpart->data = (void *)tmalloc(IFFpart->size + 1);
- __memcpy(IFFpart->data, iobMem, IFFpart->size);
- iobMem += IFFpart->size;
- }
- }
-
- return processed;
- }
-
- void pIFFtopBrushes(__memBase, register struct IFFchunk *IFFroot, register int iterVal, register struct entity *fillEntity)
- {
- struct IFFchunk *IFFpart = IFFroot;
-
- struct faces *facelist = 0;
- struct posi *origin = 0;
- struct edges *edgelist = 0;
- struct points *pointlist = 0;
- struct brush5 **brushtex = (struct brush5 **)tmalloc(15 * sizeof(struct brush5 *));
- int brushtexs = 0;
- struct facesubgroup **facegroup = (struct facesubgroup **)tmalloc(15 * sizeof(struct facesubgroup *));
- int facegroups = 0;
-
- /*
- * look for other iterated brushes
- */
- while (IFFpart) {
- struct IFFchunk *actIFFpart = IFFpart;
- int indentSpace = iterVal;
-
- while (indentSpace-- > 0) {
- oprintf(" ");
- }
- oprintf("%4s %d bytes\n", (char *)&IFFpart->type, IFFpart->size);
-
- /*
- * all types that are not DESC are for the actBrush
- * after first appeareance of DESC there are only DESCs
- */
- switch (BigLong(IFFpart->type)) {
- case ID_POSI:
- origin = (struct posi *)actIFFpart->data;
- break;
- case ID_FACE:
- facelist = (struct faces *)actIFFpart->data;
- break;
- case ID_EDGE:
- edgelist = (struct edges *)actIFFpart->data;
- break;
- case ID_PNTS:
- pointlist = (struct points *)actIFFpart->data;
- break;
- case ID_FGRP:
- case ID_FGR2:
- case ID_FGR3:
- case ID_FGR4:
- facegroup[facegroups] = (struct facesubgroup *)actIFFpart->data;
- facegroups++;
- break;
- case ID_BRS5:
- brushtex[brushtexs] = (struct brush5 *)actIFFpart->data;
- brushtexs++;
- break;
- case ID_DESC:
- pIFFtopBrushes(bspMem, actIFFpart->iter, iterVal + 1, fillEntity);
- break;
- default:
- tfree(actIFFpart->data);
- break;
- }
- IFFpart = IFFpart->next;
- tfree(actIFFpart);
- }
-
- if (facelist && edgelist && pointlist && brushtexs) {
- int i;
-
- unsigned short int facecnt;
- struct mbrush *actBrush = (struct mbrush *)tmalloc(sizeof(struct mbrush));
- struct mface *checkFace = 0;
- vec3_t middle;
- unsigned short int p0, p1, p2;
- vector *point;
-
- for (facecnt = 0; facecnt < BigShort(facelist->tcount); facecnt++) {
- p0 = edgelist->edges[BigShort(facelist->connects[facecnt][0])][0];
- p1 = edgelist->edges[BigShort(facelist->connects[facecnt][0])][1];
- if ((edgelist->edges[BigShort(facelist->connects[facecnt][1])][0] != p0) &&
- (edgelist->edges[BigShort(facelist->connects[facecnt][1])][0] != p1))
- p2 = edgelist->edges[BigShort(facelist->connects[facecnt][1])][0];
- else
- p2 = edgelist->edges[BigShort(facelist->connects[facecnt][1])][1];
-
- point = &pointlist->points[BigShort(p0)];
- middle[0] += fract2float(BigLong(point->x));
- middle[1] += fract2float(BigLong(point->y));
- middle[2] += fract2float(BigLong(point->z));
- point = &pointlist->points[BigShort(p1)];
- middle[0] += fract2float(BigLong(point->x));
- middle[1] += fract2float(BigLong(point->y));
- middle[2] += fract2float(BigLong(point->z));
- point = &pointlist->points[BigShort(p2)];
- middle[0] += fract2float(BigLong(point->x));
- middle[1] += fract2float(BigLong(point->y));
- middle[2] += fract2float(BigLong(point->z));
- }
- middle[0] /= (facecnt * 3);
- middle[1] /= (facecnt * 3);
- middle[2] /= (facecnt * 3);
-
- for (facecnt = 0; facecnt < BigShort(facelist->tcount); facecnt++) {
- int j;
- struct mface *actFace = (struct mface *)tmalloc(sizeof(struct mface));
- vec3_t t1, t2, t3;
- float distance;
-
- p0 = edgelist->edges[BigShort(facelist->connects[facecnt][0])][0];
- p1 = edgelist->edges[BigShort(facelist->connects[facecnt][0])][1];
- if ((edgelist->edges[BigShort(facelist->connects[facecnt][1])][0] != p0) &&
- (edgelist->edges[BigShort(facelist->connects[facecnt][1])][0] != p1))
- p2 = edgelist->edges[BigShort(facelist->connects[facecnt][1])][0];
- else
- p2 = edgelist->edges[BigShort(facelist->connects[facecnt][1])][1];
-
- point = &pointlist->points[BigShort(p0)];
- actFace->p0[0] = fract2float(BigLong(point->x));
- actFace->p0[1] = fract2float(BigLong(point->y));
- actFace->p0[2] = fract2float(BigLong(point->z));
- point = &pointlist->points[BigShort(p1)];
- actFace->p1[0] = fract2float(BigLong(point->x));
- actFace->p1[1] = fract2float(BigLong(point->y));
- actFace->p1[2] = fract2float(BigLong(point->z));
- point = &pointlist->points[BigShort(p2)];
- actFace->p2[0] = fract2float(BigLong(point->x));
- actFace->p2[1] = fract2float(BigLong(point->y));
- actFace->p2[2] = fract2float(BigLong(point->z));
-
- /*
- * correct to clockwise order
- * planenormal must direct to other side of middle
- * or: the middle must be in the negative side of the room splitted by the plane
- * positive distance between plane and point mean it is on the positive side
- *
- * Erzeugen der Hessischen Normalenform
- * building of hesse-normalform ? to calculate distane between plane and point
- */
- VectorSubtract(actFace->p0, actFace->p1, t1);
- VectorSubtract(actFace->p2, actFace->p1, t2);
- VectorCopy(actFace->p1, t3);
- CrossProduct(t1, t2, actFace->plane.normal);
- VectorNormalize(actFace->plane.normal);
- actFace->plane.dist = DotProduct(t3, actFace->plane.normal);
-
- if ((distance = DotProduct(middle, actFace->plane.normal) - actFace->plane.dist) > 0) {
- vec3_t temp;
-
- VectorCopy(actFace->p0, temp);
- VectorCopy(actFace->p2, actFace->p0);
- VectorCopy(temp, actFace->p2);
-
- VectorNegate(actFace->plane.normal);
- actFace->plane.dist = -actFace->plane.dist;
- }
-
- /*
- * elimination doubled faces in resulting only valid brushes
- * equal is: if normal and distance to origin are equal
- * the distance to origin is equal then if the angle between normal and normal of ?-normal is equal
- *
- * in theory in quakeMode, there are no eleminations possible
- */
- checkFace = actBrush->faces;
- while (checkFace) {
- float a, b, c;
-
- /* Abstand Punkt->Ebene / distances point->plane */
- a = fabs(DotProduct(actFace->p0, checkFace->plane.normal) - checkFace->plane.dist);
- b = fabs(DotProduct(actFace->p1, checkFace->plane.normal) - checkFace->plane.dist);
- c = fabs(DotProduct(actFace->p2, checkFace->plane.normal) - checkFace->plane.dist);
-
- /* if point->plane less than minimum, eleminate them */
- if ((a < ON_EPSILON) && (b < ON_EPSILON) && (c < ON_EPSILON))
- break;
-
- checkFace = checkFace->next;
- }
-
- if (!checkFace) {
- /*
- * get the textures
- */
- for (i = 0; i < facegroups; i++) {
- for (j = 0; j < BigShort(facegroup[i]->count); j++) {
- if (BigShort(facegroup[i]->facelist[j]) == facecnt)
- break;
- }
- if (j < BigShort(facegroup[i]->count))
- break;
- }
- for (j = 0; j < brushtexs; j++) {
- if (!__strncmp(facegroup[i]->name, brushtex[j]->subgrp, 18))
- break;
- }
- if (j < brushtexs) {
- float zero[2] =
- {0, 0};
- float one[2] =
- {1, 1};
-
- actFace->texinfo = MakeTexinfo(bspMem, brushtex[j]->name, actFace, one, 0, zero);
- }
-
- actFace->next = actBrush->faces;
- actBrush->faces = actFace;
- }
- else
- tfree(actFace);
- }
-
- tfree(facelist);
- tfree(edgelist);
- tfree(pointlist);
- for (i = 0; i < facegroups; i++)
- tfree(facegroup[i]);
- tfree(facegroup);
- for (i = 0; i < brushtexs; i++)
- tfree(brushtex[i]);
- tfree(brushtex);
-
- /*
- * put in brush
- */
- actBrush->next = fillEntity->brushes;
- fillEntity->brushes = actBrush;
- nummapbrushes++;
- }
- else
- eprintf("not enough data to convert brush!\n");
- }
-
- void pIFFtopMap(__memBase, register struct IFFchunk *IFFroot, register int iterVal)
- {
- struct IFFchunk *IFFpart = IFFroot;
-
- while (IFFpart) {
- struct IFFchunk *actIFFpart = IFFpart;
- int indentSpace = iterVal;
-
- while (indentSpace-- > 0) {
- oprintf(" ");
- }
- oprintf("%4s %d bytes\n", (char *)&actIFFpart->type, actIFFpart->size);
-
- switch (BigLong(actIFFpart->type)) {
- /*
- * only toplevel-processing (iter 0)
- */
- case ID_TDDD:
- /*
- * only toplevel-processing (iter 1)
- */
- case ID_OBJ:
- pIFFtopMap(bspMem, actIFFpart->iter, iterVal + 1);
- break;
- /*
- * only toplevel-processing (iter 2)
- */
- case ID_DESC:
- if (iterVal == 2)
- /* the dummy-axis to save the hierarchie to disk */
- pIFFtopMap(bspMem, actIFFpart->iter, iterVal + 1);
- else {
- if (actIFFpart->iter) {
- struct IFFchunk *Brushes = actIFFpart->iter;
- struct entity *thisEntity;
-
- if (bspMem->nummapentities == bspMem->max_nummapentities)
- ExpandClusters(bspMem, MAP_ENTITIES);
- thisEntity = &bspMem->mapentities[bspMem->nummapentities];
- bspMem->nummapentities++;
-
- while (Brushes) {
- if (Brushes->type == BigLong(ID_NAME)) {
- thisEntity->classname = (char *)tmalloc(__strlen(Brushes->data) + 1);
- strlwrcpy(thisEntity->classname, Brushes->data);
- }
- else if (Brushes->type == BigLong(ID_INT1)) {
- struct int1 *inten = (struct int1 *)Brushes->data;
-
- thisEntity->light = (unsigned char)rint((fract2float(BigLong(inten->intensity.x)) +
- fract2float(BigLong(inten->intensity.y)) +
- fract2float(BigLong(inten->intensity.z))) / 3);
- }
- else if (Brushes->type == BigLong(ID_SHP2)) {
- struct shap *shape = (struct shap *)Brushes->data;
-
- if ((shape->lamp & BigLong(LP2_TYPE)) != BigLong(LP2_NOLAM))
- thisEntity->style = 1;
- }
- else if (Brushes->type == BigLong(ID_POSI)) {
- struct posi *origin = (struct posi *)Brushes->data;
-
- thisEntity->origin[0] = fract2float(BigLong(origin->position.x));
- thisEntity->origin[1] = fract2float(BigLong(origin->position.y));
- thisEntity->origin[2] = fract2float(BigLong(origin->position.z));
- }
- else if (Brushes->type == BigLong(ID_TXT4)) {
- struct texture4 *brushtex = (struct texture4 *)Brushes->data;
- struct epair *lastString;
- struct epair *actString = (struct epair *)tmalloc(sizeof(struct epair));
-
- actString->next = 0;
- actString->key = (char *)tmalloc(brushtex->length + 1);
- __strncpy(actString->key, brushtex->name, brushtex->length);
- actString->key[brushtex->length] = '\0';
- actString->value = (char *)tmalloc(__strlen(brushtex->label) + 1);
- __strcpy(actString->value, brushtex->label);
-
- if ((lastString = thisEntity->epairs)) {
- while (lastString->next)
- lastString = lastString->next;
- lastString->next = actString;
- }
- else
- thisEntity->epairs = actString;
- }
- else if (Brushes->type == BigLong(ID_DESC)) {
- /*
- * after this we get no datas any more
- */
- if (Brushes->iter)
- pIFFtopBrushes(bspMem, Brushes->iter, iterVal + 1, thisEntity);
- }
- Brushes = Brushes->next;
- }
-
- /*
- * for all
- */
- if (VectorZero(thisEntity->origin))
- GetVectorForKey(thisEntity, "origin", thisEntity->origin);
- if (!thisEntity->classname)
- thisEntity->classname = ValueForKey(thisEntity, "classname");
- thisEntity->target = ValueForKey(thisEntity, "target");
- thisEntity->targetname = ValueForKey(thisEntity, "targetname");
-
- /*
- * special for qbsp+light+vis in one part
- */
- if (bspMem->mapOptions & MAP_LOADLIGHTS) {
- if (!(thisEntity->light = FloatForKeyN(thisEntity, "light")))
- if (!(thisEntity->light = FloatForKey(thisEntity, "_light")))
- if (!thisEntity->light)
- thisEntity->light = MAX_MAPLIGHTLEVEL;
- if (!(thisEntity->style = FloatForKey(thisEntity, "style")))
- if (!(thisEntity->style = FloatForKey(thisEntity, "_style")))
- if (!thisEntity->style)
- thisEntity->style = 0;
- if (!thisEntity->angle)
- thisEntity->angle = FloatForKey(thisEntity, "angle");
-
- if (__strcmp(thisEntity->classname, "light")) {
- if (!thisEntity->light)
- thisEntity->light = DEFAULTLIGHTLEVEL;
-
- if (thisEntity->targetname[0] && !thisEntity->style) {
- char s[256];
-
- thisEntity->style = LightStyleForTargetname(thisEntity->targetname, TRUE);
- sprintf(s, "%i", thisEntity->style);
- SetKeyValue(thisEntity, "style", s);
- }
- }
- }
- }
- }
- break;
- default:
- break;
- }
- IFFpart = IFFpart->next;
- tfree(actIFFpart->data);
- tfree(actIFFpart);
- }
- }
-
- /*
- * the rules:
- *
- * -the hierarchy:
- *
- * DESC "world/axis/root" (axis)
- * -> acts as global group-manager to save all subhierarchies
- * DESC "worldspawn" (axis)
- * -> all subdesc's desribes the brushes (objects grouped to axis "worldspawn")
- * -> all subdesc's texture info must contain the name of the texture to use and
- * the alignment/positioning must be valid
- * DESC "info_player_start" (axis)
- * -> the axis position describes the players origin
- * DESC "standard quake"
- * -> will be searched for information
- * (eg. DESC "light" (axis with light) is the standard entity "light", parameters
- * are parsed out of the axis-informations)
- * -> axis that are groupt to a non-worldspawn-entity and that have no brushes
- * will beinterpreted as movement-points (?)
- * -> the texture-list of an entity will be parsed for key-values (standard-quake
- * like "target")
- *
- * restriction:
- *
- * dont make objects, that are not convex
- * calculation of clockwise point-order goes via middlepoint of object
- *
- */
-
- /*
- * ================
- * SaveTDDDFile
- * ================
- */
- bool SaveTDDDFile(__memBase, HANDLE outFile)
- {
- struct entity *ent;
- struct epair *ep;
- struct mbrush *b;
- struct mface *f;
- int i;
- struct dmiptexlump_t *head_miptex = (struct dmiptexlump_t *)bspMem->shared.quake1.dtexdata;
- int lastTDDD = 0;
- int lastObj = 0;
- int lastWorld = 0;
- int lastRoot = 0;
- int lastDesc = 0;
-
- /*
- * hierarchy:
- *
- * TDDD
- * OBJ
- * DESC worldaxis
- * | DESC worldspawn
- * | | DESC model1
- * | | +-TOBJ
- * | | DESC model2
- * | | +-TOBJ
- * | | ...
- * | +-TOBJ
- * | DESC light
- * | ...
- * +-TOBJ
- */
-
- SetForm(outFile, &lastTDDD, ID_TDDD);
- SetRoot(outFile, &lastObj, ID_OBJ);
-
- SetRoot(outFile, &lastWorld, ID_DESC);
- SetClassName(outFile, "worldaxis");
- SetOtherDefaults(outFile, 0);
- VerRoot(outFile, &lastWorld, ID_DESC);
-
- /* set worldspawn as root of all the other models */
- SetRoot(outFile, &lastRoot, ID_DESC);
- for (i = 0, ent = bspMem->mapentities; i < bspMem->nummapentities; i++, ent++)
- if (!__strcmp(ent->classname, "worldspawn"))
- break;
-
- if (i == bspMem->nummapentities) {
- eprintf("SaveTDDDFile: worldspawn not found!\n");
- return FALSE;
- }
-
- SetClassName(outFile, ent->classname);
- for (ep = ent->epairs; ep; ep = ep->next)
- if (__strcmp(ep->key, "model"))
- SetEntity(outFile, ep->key, ep->value);
- for (b = ent->brushes; b; b = b->next) {
- for (f = b->faces; f; f = f->next) {
- struct texinfo *texinfo = &bspMem->shared.quake1.texinfo[f->texinfo];
- char *miptexname;
-
- if (head_miptex) /* for an allready compiled map */
- miptexname = ((struct mipmap *)(bspMem->shared.quake1.dtexdata + head_miptex->dataofs[texinfo->miptex]))->name;
- else if (bspMem->maptexstrings) /* for an uncompiled map */
- miptexname = bspMem->maptexstrings[texinfo->miptex];
- else /* for unknown states */
- miptexname = "unknown\0";
-
- SaveFace(f->p0, f->p1, f->p2, miptexname);
- }
- }
- SetPoints(outFile);
- SetEdges(outFile);
- SetFaces(outFile);
- SetBrushes(outFile);
- SetOtherDefaults(outFile, ent);
- VerRoot(outFile, &lastRoot, ID_DESC);
-
- for (i = 0, ent = bspMem->mapentities; i < bspMem->nummapentities; i++, ent++) {
- bool model = FALSE;
-
- for (ep = ent->epairs; ep; ep = ep->next) {
- if (!__strcmp(ep->key, "model")) {
- model = TRUE;
- break;
- }
- }
-
- if (model && __strcmp(ent->classname, "worldspawn")) {
- SetRoot(outFile, &lastDesc, ID_DESC);
- SetClassName(outFile, ent->classname);
- for (ep = ent->epairs; ep; ep = ep->next)
- if (__strcmp(ep->key, "model"))
- SetEntity(outFile, ep->key, ep->value);
- for (b = ent->brushes; b; b = b->next) {
- for (f = b->faces; f; f = f->next) {
- struct texinfo *texinfo = &bspMem->shared.quake1.texinfo[f->texinfo];
- char *miptexname;
-
- if (head_miptex) /* for an allready compiled map */
- miptexname = ((struct mipmap *)(bspMem->shared.quake1.dtexdata + head_miptex->dataofs[texinfo->miptex]))->name;
- else if (bspMem->maptexstrings) /* for an uncompiled map */
- miptexname = bspMem->maptexstrings[texinfo->miptex];
- else /* for unknown states */
- miptexname = "unknown\0";
-
- SaveFace(f->p0, f->p1, f->p2, miptexname);
- }
- }
- SetPoints(outFile);
- SetEdges(outFile);
- SetFaces(outFile);
- SetBrushes(outFile);
- SetOtherDefaults(outFile, ent);
- VerRoot(outFile, &lastDesc, ID_DESC);
- SetEndM(outFile, ID_TOBJ);
- }
- }
- SetEndM(outFile, ID_TOBJ);
- VerRoot(outFile, &lastObj, ID_OBJ);
- VerRoot(outFile, &lastTDDD, ID_FORM);
-
- mprintf("----- SaveTDDDFile -------\n");
- mprintf("%5i points\n", TDDDnumpoints);
- mprintf("%5i edges\n", TDDDnumedges);
- mprintf("%5i faces\n", TDDDnumfaces);
- mprintf("%5i groups\n", TDDDnumgroups);
- mprintf("%5i objects\n", TDDDnumobjects);
-
- return TRUE;
- }
-
- /*
- * ================
- * LoadTDDDFile
- * ================
- */
- bool LoadTDDDFile(__memBase, unsigned char *tdddBuf)
- {
- struct IFFheader IFFfile =
- {0, 0, 0};
- struct IFFchunk *IFFroot = (struct IFFchunk *)tmalloc(sizeof(struct IFFchunk));
-
- __memcpy(&IFFfile, tdddBuf, 12);
- tdddBuf += 12;
- IFFroot->type = IFFfile.type;
- IFFroot->size = IFFfile.size - 4;
- IFFroot->next = 0;
- IFFroot->iter = 0;
- IFFroot->data = 0;
- memIFFtopIFF(tdddBuf, IFFroot);
- pIFFtopMap(bspMem, IFFroot, 0);
- MatchTargets(bspMem);
-
- mprintf("----- LoadTDDDFile -------\n");
- mprintf("%5i brushes\n", nummapbrushes);
- mprintf("%5i entities\n", bspMem->nummapentities);
- mprintf("%5i miptex\n", bspMem->nummaptexstrings);
- mprintf("%5i texinfo\n", bspMem->shared.quake1.numtexinfo);
-
- return TRUE;
- }
-